#include "abb.h"
#include "pila.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>

#define ARBOL_SIMPLE 1
#define ARBOL_COMPLETO 2
#define ARBOL_UNA_RAMA 3

#define CANT_CLAVES_SIMPLE 3
#define CANT_CLAVES_COMPLETO 17
#define CANT_CLAVES_UNA_RAMA 6


/* ******************************************************************
 *                      FUNCIONES AUXILIARES
 * *****************************************************************/

/* Función auxiliar para imprimir si estuvo OK o no. */
void print_test(char* name, bool result)
{
    printf("%s: %s\n", name, result? "OK" : "ERROR");
}

/* ******************************************************************
 *                        PRUEBAS UNITARIAS
 * *****************************************************************/

/* Prueba que las primitivas del abb funcionen correctamente. */
void prueba_crear_abb_vacio(){

	abb_t* arbol = abb_crear(strcmp, NULL);
	print_test("Prueba abb crear abb vacio", arbol);
	print_test("Prueba abb la cantidad de elementos es 0", abb_cantidad(arbol) == 0);
	print_test("Prueba abb obtener clave A, es NULL, no existe", !abb_obtener(arbol, "A"));
	print_test("Prueba abb pertenece clave A, es false, no existe", !abb_pertenece(arbol, "A"));
	print_test("Prueba abb borrar clave A, es NULL, no existe", !abb_borrar(arbol, "A"));

	abb_destruir(arbol);
}

// Guarda la cantidad de claves pasada por parametro en el arbol, verificando que se hayan
// guardado correctamente.
// Pre: el arbol, claves y valores fueron creados.
// Post: se guadaron la cantidad de claves y sus valores en el arbol.
void abb_guardar_con_cantidad(abb_t *arbol, char **claves, char **valores, int cant_claves){
	int i;
	bool guardar;
	for (i=0; i<cant_claves; i++){
		guardar = abb_guardar(arbol, claves[i], valores[i]);
		if (!guardar) break;
	}
	print_test("Prueba arbol insertar claves y valores", guardar);
	print_test("Prueba arbol la cantidad de elementos es correcta", abb_cantidad(arbol) == cant_claves);

	bool obtener;
	bool pertenece;
	for (i=0; i<cant_claves; i++){
		obtener = abb_obtener(arbol, claves[i]) == valores[i];
		if (!obtener) break;
		pertenece = abb_pertenece(arbol, claves[i]);
		if (!pertenece) break;
	}
	print_test("Prueba arbol obtener claves con valores correspondientes", obtener);
	print_test("Prueba arbol pertenece clave, es true", pertenece);
}

// Borra la cantidad de claves pasada por parametro del arbol, verificando que se hayan
// borrado correctamente.
// Pre: el arbol fue creado.
// Post: se borraron la cantidad de claves y sus valores del arbol.
void abb_borrar_con_cantidad(abb_t *arbol, char **claves, char **valores, int cant_claves){
	bool pertenece = false;
	bool no_pertenece = false;
	bool borrar1 = false;
	bool no_borrar = false;
	bool obtener = false;
	bool cantidad = false;

	int i;
	for (i=cant_claves-1; i>=0; i--){
		pertenece = abb_pertenece(arbol, claves[i]);
		if (!pertenece) break;
		borrar1 = abb_borrar(arbol, claves[i]) == valores[i];
		if (!borrar1) break;
		no_borrar = abb_borrar(arbol, claves[i]);
		if (no_borrar) break;
		no_pertenece = !abb_pertenece(arbol, claves[i]);
		if (!no_pertenece) break;
		obtener = !abb_obtener(arbol, claves[i]);
		if (!obtener) break;
		cantidad = abb_cantidad(arbol) == i;
		if (!cantidad) break;
	}
	print_test("Prueba arbol pertenecen las claves", pertenece);
	print_test("Prueba arbol borrar clave, es valor correspondiente", borrar1);
	print_test("Prueba arbol borrar clave nuevamente, es NULL", !no_borrar);
	print_test("Prueba arbol pertenece clave borrada, es falso", no_pertenece);
	print_test("Prueba arbol obtener clave borrada, es NULL", obtener);
	print_test("Prueba arbol la cantidad de elementos es correcta", cantidad);
}

// Crea un arbol del tipo indicado por "arbol_tipo". Guarda cant_claves claves en el arbol, verificando
// que se hayan guardado correctamente. Si borrar es true se borraran cant_claves del arbol, si es false
// no se borra ninguna clave.
// Post: se creo el arbol, se guadaron la cantidad de claves y sus valores en el arbol.
abb_t *abb_crear_guardar_con_cantidad(int arbol_tipo, int cant_claves, bool borrar){
	abb_t* arbol = abb_crear(strcmp, NULL);

	if (arbol_tipo == ARBOL_SIMPLE){
		char *claves1[] = {"perro", "gato", "vaca"};

		char *valores1[] = {"carnivoro", "carnivoro", "herbivoro"};
		/*		   "perro"
					/	\
			   "gato"  "vaca",
		*/
		abb_guardar_con_cantidad(arbol, claves1, valores1, cant_claves);
		if (borrar)
			abb_borrar_con_cantidad(arbol, claves1, valores1, cant_claves);
	}
	if (arbol_tipo == ARBOL_COMPLETO){
		char *claves2[] = {"perro", "gato", "vaca", "buitre", "oso", "serpiente", "yaguarete", "aveja", "foca",
		"jirafa", "oveja", "rana", "tortuga", "yacare", "zorro", "rinoceronte", "leopardo"};

		char *valores2[] = {"carnivoro", "carnivoro", "herbivoro", "carroniero", "omnivoro", "carnivoro",
		"carnivoro", "herbivoro", "carnivoro", "herbivoro", "herbivoro", "carnivoro", "omnivoro", "carnivoro",
		"carnivoro", "herbivoro", "carnivoro"};
		/*
											  "perro"
								  /	                          \
						   "gato"	                            "vaca"
						 /        \	                          /        \
				"buitre"           "oso"            "serpiente"          "jaguarete"
				  / \			   /   \             /       \            /      \
			aveja"   "foca"  "jirafa"  "oveja"  "rana"      "tortuga" "yacare"   "zorro"
									\				 \
									"leopardo"		 "rinoceronte"
		*/
		abb_guardar_con_cantidad(arbol, claves2, valores2, cant_claves);
		if (borrar)
			abb_borrar_con_cantidad(arbol, claves2, valores2, cant_claves);
	}
	if (arbol_tipo == ARBOL_UNA_RAMA){
		char *claves3[] = {"perro", "oso", "jirafa", "gato", "buitre", "aveja"};

		char *valores3[] = {"carnivoro", "omnivoro", "herbivoro", "carnivoro", "carroniero", "carnivoro"};
		/*
					  "perro"
					   /
					"oso"
					 /
				 "jirafa"
				   /
				"gato"
				 /
			 "buitre"
			   /
			aveja"
		*/
		abb_guardar_con_cantidad(arbol, claves3, valores3, cant_claves);
		if (borrar)
			abb_borrar_con_cantidad(arbol, claves3, valores3, cant_claves);
	}

	return arbol;
}

void prueba_abb_insertar(){
	puts("Prueba insertar con arbol simple");
	abb_t* arbol_simple = abb_crear_guardar_con_cantidad(ARBOL_SIMPLE, CANT_CLAVES_SIMPLE, false);
	abb_destruir(arbol_simple);

	puts("Prueba insertar con arbol completo");
	abb_t* arbol_completo = abb_crear_guardar_con_cantidad(ARBOL_COMPLETO, CANT_CLAVES_COMPLETO, false);
	abb_destruir(arbol_completo);

	puts("Prueba insertar con arbol de una rama");
	abb_t* arbol_una_rama = abb_crear_guardar_con_cantidad(ARBOL_UNA_RAMA, CANT_CLAVES_UNA_RAMA, false);
	abb_destruir(arbol_una_rama);
}

void prueba_abb_reemplazar(){
	abb_t* arbol = abb_crear(strcmp, NULL);

	char *clave1 = "perro", *valor1a = "guau", *valor1b = "warf";
	char *clave2 = "gato", *valor2a = "miau", *valor2b = "meaow";

	/* Inserta 2 valores y luego los reemplaza */
	print_test("Prueba arbol insertar clave1", abb_guardar(arbol, clave1, valor1a));
	print_test("Prueba arbol obtener clave1 es valor1a", abb_obtener(arbol, clave1) == valor1a);
	print_test("Prueba arbol obtener clave1 es valor1a", abb_obtener(arbol, clave1) == valor1a);
	print_test("Prueba arbol insertar clave2", abb_guardar(arbol, clave2, valor2a));
	print_test("Prueba arbol obtener clave2 es valor2a", abb_obtener(arbol, clave2) == valor2a);
	print_test("Prueba arbol obtener clave2 es valor2a", abb_obtener(arbol, clave2) == valor2a);
	print_test("Prueba arbol la cantidad de elementos es 2", abb_cantidad(arbol) == 2);

	print_test("Prueba arbol insertar clave1 con otro valor", abb_guardar(arbol, clave1, valor1b));
	print_test("Prueba arbol obtener clave1 es valor1b", abb_obtener(arbol, clave1) == valor1b);
	print_test("Prueba arbol obtener clave1 es valor1b", abb_obtener(arbol, clave1) == valor1b);
	print_test("Prueba arbol insertar clave2 con otro valor", abb_guardar(arbol, clave2, valor2b));
	print_test("Prueba arbol obtener clave2 es valor2b", abb_obtener(arbol, clave2) == valor2b);
	print_test("Prueba arbol obtener clave2 es valor2b", abb_obtener(arbol, clave2) == valor2b);
	print_test("Prueba arbol la cantidad de elementos es 2", abb_cantidad(arbol) == 2);

	abb_destruir(arbol);
}

void prueba_abb_reemplazar_con_destruir(){
	abb_t* arbol = abb_crear(strcmp, free);

	char *clave1 = "par";
	char *clave2 = "impar";

	/* Pide memoria para 4 valores */
	int *valor1a = malloc(sizeof(int));
	*valor1a = 12;
	int *valor1b = malloc(sizeof(int));
	*valor1b = 34;
	int *valor2a = malloc(sizeof(int));
	*valor2a = 19;
	int *valor2b = malloc(sizeof(int));
	*valor2b = 17;

	/* Inserta 2 valores y luego los reemplaza (debe liberar lo que reemplaza) */
	print_test("Prueba arbol insertar clave1", abb_guardar(arbol, clave1, valor1a));
	print_test("Prueba arbol obtener clave1 es valor1a", abb_obtener(arbol, clave1) == valor1a);
	print_test("Prueba arbol obtener clave1 es valor1a", abb_obtener(arbol, clave1) == valor1a);
	print_test("Prueba arbol insertar clave2", abb_guardar(arbol, clave2, valor2a));
	print_test("Prueba arbol obtener clave2 es valor2a", abb_obtener(arbol, clave2) == valor2a);
	print_test("Prueba arbol obtener clave2 es valor2a", abb_obtener(arbol, clave2) == valor2a);
	print_test("Prueba arbol la cantidad de elementos es 2", abb_cantidad(arbol) == 2);

	print_test("Prueba arbol insertar clave1 con otro valor", abb_guardar(arbol, clave1, valor1b));
	print_test("Prueba arbol obtener clave1 es valor1b", abb_obtener(arbol, clave1) == valor1b);
	print_test("Prueba arbol obtener clave1 es valor1b", abb_obtener(arbol, clave1) == valor1b);
	print_test("Prueba arbol insertar clave2 con otro valor", abb_guardar(arbol, clave2, valor2b));
	print_test("Prueba arbol obtener clave2 es valor2b", abb_obtener(arbol, clave2) == valor2b);
	print_test("Prueba arbol obtener clave2 es valor2b", abb_obtener(arbol, clave2) == valor2b);
	print_test("Prueba arbol la cantidad de elementos es 2", abb_cantidad(arbol) == 2);

	/* Se destruye el arbol (se debe liberar lo que quedó dentro) */
	abb_destruir(arbol);
}

void prueba_abb_borrar(){
	puts("Prueba borrar todo arbol simple");
	abb_t* arbol_simple = abb_crear_guardar_con_cantidad(ARBOL_SIMPLE, CANT_CLAVES_SIMPLE, true);
	abb_destruir(arbol_simple);

	puts("Prueba borrar todo arbol completo");
	abb_t* arbol_completo = abb_crear_guardar_con_cantidad(ARBOL_COMPLETO, CANT_CLAVES_COMPLETO, true);
	abb_destruir(arbol_completo);

	puts("Prueba borrar todo arbol una rama");
	abb_t* arbol_una_rama = abb_crear_guardar_con_cantidad(ARBOL_UNA_RAMA, CANT_CLAVES_UNA_RAMA, true);
	abb_destruir(arbol_una_rama);

	puts("Prueba borrar con arbol completo un nodo con dos hijos");
	abb_t* arbol_completo2 = abb_crear_guardar_con_cantidad(ARBOL_COMPLETO, CANT_CLAVES_COMPLETO, false);
	abb_borrar(arbol_completo2, "vaca");
	abb_destruir(arbol_completo2);

	puts("Prueba borrar con arbol completo un nodo con dos hijos");
	abb_t* arbol_completo3 = abb_crear_guardar_con_cantidad(ARBOL_COMPLETO, CANT_CLAVES_COMPLETO, false);
	abb_borrar(arbol_completo3, "gato");
	abb_destruir(arbol_completo3);

	puts("Prueba borrar con arbol completo un nodo hoja");
	abb_t* arbol_completo4 = abb_crear_guardar_con_cantidad(ARBOL_COMPLETO, CANT_CLAVES_COMPLETO, false);
	abb_borrar(arbol_completo4, "aveja");
	abb_destruir(arbol_completo4);

	puts("Prueba borrar con arbol una rama un nodo con un hijo");
	abb_t* arbol_una_rama2 = abb_crear_guardar_con_cantidad(ARBOL_UNA_RAMA, CANT_CLAVES_UNA_RAMA, false);
	abb_borrar(arbol_una_rama2, "gato");
	abb_destruir(arbol_una_rama2);

	puts("Prueba borrar con arbol simple la raiz con hijos");
	abb_t* arbol_simple2 = abb_crear_guardar_con_cantidad(ARBOL_SIMPLE, CANT_CLAVES_SIMPLE, false);
	abb_borrar(arbol_simple2, "perro");
	abb_destruir(arbol_simple2);
}

void prueba_abb_clave_vacia(){
	abb_t* arbol = abb_crear(strcmp, NULL);

	char *clave = "", *valor = "";

	print_test("Prueba arbol insertar clave vacia", abb_guardar(arbol, clave, valor));
	print_test("Prueba arbol la cantidad de elementos es 1", abb_cantidad(arbol) == 1);
	print_test("Prueba arbol obtener clave vacia es valor", abb_obtener(arbol, clave) == valor);
	print_test("Prueba arbol pertenece clave vacia, es true", abb_pertenece(arbol, clave));
	print_test("Prueba arbol borrar clave vacia, es valor", abb_borrar(arbol, clave) == valor);
	print_test("Prueba arbol la cantidad de elementos es 0", abb_cantidad(arbol) == 0);

	abb_destruir(arbol);
}

void prueba_abb_valor_null(){
	abb_t* arbol = abb_crear(strcmp, NULL);

	char *clave = "", *valor = NULL;

	/* Inserta 1 valor y luego lo borra */
	print_test("Prueba arbol insertar clave vacia valor NULL", abb_guardar(arbol, clave, valor));
	print_test("Prueba arbol la cantidad de elementos es 1", abb_cantidad(arbol) == 1);
	print_test("Prueba arbol obtener clave vacia es valor NULL", abb_obtener(arbol, clave) == valor);
	print_test("Prueba arbol pertenece clave vacia, es true", abb_pertenece(arbol, clave));
	print_test("Prueba arbol borrar clave vacia, es valor NULL", abb_borrar(arbol, clave) == valor);
	print_test("Prueba arbol la cantidad de elementos es 0", abb_cantidad(arbol) == 0);

	abb_destruir(arbol);
}

void prueba_abb_volumen(size_t largo, bool debug){
	abb_t* arbol = abb_crear(strcmp, NULL);

	const size_t largo_clave = 10;
	char (*claves)[largo_clave] = malloc(largo * largo_clave);

	int* valores[largo];

	/* Inserta 'largo' parejas en el abb */
	bool ok = true;
	for (int i = 0; i < largo; i++) {
		valores[i] = malloc(sizeof(int));
		sprintf(claves[i], "%08d", i);
		*valores[i] = i;
		ok = abb_guardar(arbol, claves[i], valores[i]);
		if (!ok) break;
	}

	if (debug) print_test("Prueba arbol almacenar muchos elementos", ok);
	if (debug) print_test("Prueba arbol la cantidad de elementos es correcta", abb_cantidad(arbol) == largo);

	/* Verifica que devuelva los valores correctos */	
	for (size_t i = 0; i < largo; i++) {
		ok = abb_pertenece(arbol, claves[i]);
		if (!ok) break;
		ok = abb_obtener(arbol, claves[i]) == valores[i];
		if (!ok) break;
	}

	if (debug) print_test("Prueba arbol pertenece y obtener muchos elementos", ok);
	if (debug) print_test("Prueba arbol la cantidad de elementos es correcta", abb_cantidad(arbol) == largo);

	/* Verifica que borre y devuelva los valores correctos */
	for (size_t i = 0; i < largo; i++) {
		ok = abb_borrar(arbol, claves[i]) == valores[i];
		if (!ok) break;
	}

	if (debug) print_test("Prueba arbol borrar muchos elementos", ok);
	if (debug) print_test("Prueba arbol la cantidad de elementos es 0", abb_cantidad(arbol) == 0);

	/* Destruye el abb y crea uno nuevo que sí libera */
	abb_destruir(arbol);
	arbol = abb_crear(strcmp, free);

	/* Inserta 'largo' parejas en el abb */
	ok = true;
	for (size_t i = 0; i < largo; i++) {
		ok = abb_guardar(arbol, claves[i], valores[i]);
		if (!ok) break;
	}

	free(claves);
	
	/* Destruye el abb - debería liberar los enteros */
	abb_destruir(arbol);

}

void prueba_iterar_abb_vacio(){
	abb_t* arbol = abb_crear(strcmp, NULL);
	abb_iter_t* iter = abb_iter_in_crear(arbol);
	print_test("Prueba arbol iter crear iterador arbol vacio", iter);
	print_test("Prueba arbol iter esta al final", abb_iter_in_al_final(iter));
	print_test("Prueba arbol iter avanzar es false", !abb_iter_in_avanzar(iter));
	print_test("Prueba arbol iter ver actual es NULL", !abb_iter_in_ver_actual(iter));

	abb_iter_in_destruir(iter);
	abb_destruir(arbol);
}

int buscar(const char* clave, char* claves[], size_t largo){
	for (size_t i = 0; i < largo; i++) {
		if (strcmp(clave, claves[i]) == 0) return i;
	}
	return -1;
}

void prueba_abb_iterar(){
	abb_t* arbol = abb_crear(strcmp, NULL);
	
	char *claves[] = {"perro", "gato", "vaca"};
	char *valores[] = {"guau", "miau", "mu"};

	/* Inserta 3 valores */
	print_test("Prueba arbol insertar clave1", abb_guardar(arbol, claves[0], valores[0]));
	print_test("Prueba arbol insertar clave2", abb_guardar(arbol, claves[1], valores[1]));
	print_test("Prueba arbol insertar clave3", abb_guardar(arbol, claves[2], valores[2]));

	// Prueba de iteración sobre las claves almacenadas.
	abb_iter_t* iter = abb_iter_in_crear(arbol);
	const char *clave;
	int indice;
	
	print_test("Prueba arbol iterador esta al final, es false", !abb_iter_in_al_final(iter));

	/* Primer valor */
	clave = abb_iter_in_ver_actual(iter);
	indice = buscar(clave, claves, sizeof(claves));
	print_test("Prueba arbol iterador ver actual, es una clave valida", indice != -1);
	print_test("Prueba arbol iterador ver actual, es gato", strcmp(clave, claves[1]) == 0);
	print_test("Prueba arbol iterador avanzar es true", abb_iter_in_avanzar(iter));
	print_test("Prueba arbol iterador esta al final, es false", !abb_iter_in_al_final(iter));

	/* Segundo valor */
	clave = abb_iter_in_ver_actual(iter);
	indice = buscar(clave, claves, sizeof(claves));
	print_test("Prueba arbol iterador ver actual, es una clave valida", indice != -1);
	print_test("Prueba arbol iterador ver actual, es perro", strcmp(clave, claves[0]) == 0);
	print_test("Prueba arbol iterador avanzar es true", abb_iter_in_avanzar(iter));
	print_test("Prueba arbol iterador esta al final, es false", !abb_iter_in_al_final(iter));

	/* Tercer valor */
	clave = abb_iter_in_ver_actual(iter);
	indice = buscar(clave, claves, sizeof(claves));
	print_test("Prueba arbol iterador ver actual, es una clave valida", indice != -1);
	print_test("Prueba arbol iterador ver actual, es vaca", strcmp(clave, claves[2]) == 0);
	/* Se anula esta prueba por diferencias de criterios */
	abb_iter_in_avanzar(iter);
	print_test("Prueba arbol iterador esta al final, es true", abb_iter_in_al_final(iter));

	/* Vuelve a tratar de avanzar, por las dudas */
	print_test("Prueba arbol iterador ver actual, es NULL", !abb_iter_in_ver_actual(iter));
	print_test("Prueba arbol iterador avanzar es false", !abb_iter_in_avanzar(iter));
	print_test("Prueba arbol iterador esta al final, es true", abb_iter_in_al_final(iter));

	abb_iter_in_destruir(iter);
	abb_destruir(arbol);
}

void prueba_abb_iterar_volumen(size_t largo){
	abb_t* arbol = abb_crear(strcmp, NULL);

	const size_t largo_clave = 10;
	char (*claves)[largo_clave] = malloc(largo * largo_clave);

	int valores[largo];

	/* Inserta 'largo' parejas en el arbol */
	bool ok = true;
	for (int i = 0; i < largo; i++) {
		sprintf(claves[i], "%08d", i);
		valores[i] = i;
		ok = abb_guardar(arbol, claves[i], &valores[i]);
		if (!ok) break;
	}

	// Prueba de iteración sobre las claves almacenadas.
	abb_iter_t* iter = abb_iter_in_crear(arbol);
	print_test("Prueba arbol iterador esta al final, es false", !abb_iter_in_al_final(iter));

	ok = true;
	int i;
	const char *clave;
	int *valor;
	
	for (i = 0; i < largo; i++) {
		if ( abb_iter_in_al_final(iter) ) {
			ok = false;
			break;
		}
		clave = abb_iter_in_ver_actual(iter);
		if ( clave == NULL ) {
			ok = false;
			break;
		}
		valor = abb_obtener(arbol, clave);
		if ( valor == NULL ) {
			ok = false;
			break;
		}
		*valor = largo;
		abb_iter_in_avanzar(iter);
	}
	print_test("Prueba arbol iteración en volumen", ok);
	print_test("Prueba arbol iteración en volumen, recorrio todo el largo", i == largo);
	if (i != largo) printf("Largo recorrido: %d\n", i);
	print_test("Prueba arbol iterador esta al final, es true", abb_iter_in_al_final(iter));

	ok = true;
	for (i = 0; i < largo; i++) {
		if ( valores[i] != largo ) {
			ok = false;
			break;
		}
	}
	print_test("Prueba arbol iteración en volumen, se cambiaron todo los elementos", ok);

	free(claves);
	abb_iter_in_destruir(iter);
	abb_destruir(arbol);
}

// Funcion que apila las claves del arbol en la pila extra. Siempre devuelve true.
// Pre: dato y extra fueron creados.
// Post: las claves se apilaron en la pila.
bool animales_en_orden_alfabetico1(const char *clave, void *dato, void *extra){
	pila_t *pila = extra;
	pila_apilar(pila, (char *) clave);
	return true;
}

// Funcion que apila las claves del arbol en la pila extra. Devuelve false si la clave es gato,
// sino devuelve true.
// Pre: dato y extra fueron creados.
// Post: las claves se apilaron en la pila.
bool animales_en_orden_alfabetico2(const char *clave, void *dato, void *extra){
	pila_t *pila = extra;
	pila_apilar(pila, (char *) clave);
	if (strcmp(clave, "gato") == 0)
		return false;
	return true;
}

// Devuelve true si los elementos de la pila estan en orden inverso al alfabetico, false en caso contrario.
// Pre: La pila fue creada.
bool palabras_en_orden(pila_t *pila){
	while (!pila_esta_vacia(pila)){
		void *palabra1 = pila_desapilar(pila);
		if (pila_esta_vacia(pila)) break;
		void *palabra2 = pila_ver_tope(pila);
		if (strcmp(palabra1, palabra2)<0)
			return false;
	}
	return true;
}

void prueba_abb_in_order(){
	puts("Prueba iterador in order con arbol completo");
	abb_t* arbol_completo = abb_crear_guardar_con_cantidad(ARBOL_COMPLETO, CANT_CLAVES_COMPLETO, false);
	pila_t *pila = pila_crear();

	print_test("La pila para guardar las palabras se creo correctamente", pila != NULL);
	abb_in_order(arbol_completo, animales_en_orden_alfabetico1, pila);
	print_test("Las palabras se encuentran en orden alfabetico", palabras_en_orden(pila));

	abb_destruir(arbol_completo);

	puts("Prueba iterador in order con arbol una rama");
	abb_t* arbol_una_rama = abb_crear_guardar_con_cantidad(ARBOL_UNA_RAMA, CANT_CLAVES_UNA_RAMA, false);

	// Se utiliza la misma pila que antes ya que esta quedo vacia.
	abb_in_order(arbol_una_rama, animales_en_orden_alfabetico2, pila);
	// Como gato se encuentra en el arbol, en el tope de la pila se debe encontrar este.
	print_test("La palabra gato se encuentran en el tope de la pila", strcmp(pila_ver_tope(pila), "gato") == 0);
	print_test("Las palabras se encuentran en orden alfabetico", palabras_en_orden(pila));

	pila_destruir(pila);
	abb_destruir(arbol_una_rama);
}



// Programa principal.
int main() {
	prueba_crear_abb_vacio();
	prueba_abb_insertar();
	prueba_abb_reemplazar();
	prueba_abb_reemplazar_con_destruir();
	prueba_abb_borrar();
	prueba_abb_clave_vacia();
	prueba_abb_valor_null();
	prueba_abb_volumen(1000, true);

	prueba_iterar_abb_vacio();
	prueba_abb_iterar();
	prueba_abb_iterar_volumen(1000);
	prueba_abb_in_order();

	return 0;
}